#ifndef STORAGE_STORAGE_FACTORY
#define STORAGE_STORAGE_FACTORY

#include "Storage/StorageConfig.hpp"

namespace Model { class Project; class Package; class Requirement;}

namespace Storage
{

class ProjectStorage;
class PackageStorage;
class RequirementsStorage;
class StorageCommand;

/// @ingroup Storage
/// @brief It provides access to various storages, specialized on different storage entities.
class STORAGE_API StorageFactory
{
public:
	/// @Brief Dummy destructor.
	virtual ~StorageFactory();

	/// @brief It should return the storage for projects.
	virtual ProjectStorage& getProjectStorage() = 0;

	/// @brief It should return the storage for packages.
	virtual PackageStorage& getPackageStorage() = 0;

	/// @brief It should return the storage for requirements.
	virtual RequirementsStorage& getRequirementStorage() = 0;

	/// @brief It creates a command for insertion of a project in the storage.
	/// @param subject the project to be inserted.
	virtual StorageCommand* createProjectCreationCommand( Model::Project& subject) = 0;

	/// @brief It creates a command for insertion of a package in the storage.
	/// @param subject the package to be inserted.
	virtual StorageCommand* createPackageCreationCommand( Model::Package& subject) = 0;

	/// @brief It creates a command for removal of a package from the storage.
	/// @param subject the package to be removed.
	virtual StorageCommand* createPackageRemovalCommand( Model::Package& subject) = 0;

	/// @brief It creates a command for creation of a requirement in the storage.
	virtual StorageCommand* createRootRequirementCreationCommand( Model::Requirement& subject) = 0;

	/// @brief It creates a command for removal of a requirement from the storage.
	virtual StorageCommand* createRootRequirementRemovalCommand( Model::Requirement& subject, Model::Package* pParentPackage) = 0;

	/// @brief It checks whether there are changes not saved (some of the managed storages have storage commands not 
	///		executed).
	virtual bool hasUnsavedChanges() const;
};
	
} // namespace Storage

#endif // STORAGE_STORAGE_FACTORY
